package com.huitone.gddw.controller.worktable.paramconfigmanage;

import com.huitone.gddw.common.ComConstant;
import com.huitone.gddw.common.CsvUtils;
import com.huitone.gddw.common.ExcelUtils;
import com.huitone.gddw.common.FileUtils;
import com.huitone.gddw.common.excel.CreateExcel;
import com.huitone.gddw.controller.common.CommonController;
import com.huitone.gddw.dao.entity.SmLog;
import com.huitone.gddw.dao.entity.SvrNodeDef;
import com.huitone.gddw.dao.entity.UploadFile;
import com.huitone.gddw.dao.entity.WebSmRec;
import com.huitone.gddw.model.support.Message;
import com.huitone.gddw.model.support.QueryPage;
import com.huitone.gddw.service.ISvrNodeDefService;
import com.huitone.gddw.service.IUploadFileService;
import com.huitone.gddw.service.business.IWebSmRecService;
import com.huitone.gddw.service.dto.UploadFileDTO;
import com.huitone.gddw.service.dto.business.UploadWebSmDTO;
import com.huitone.gddw.utils.ContextPropertiesUtils;
import com.huitone.gddw.utils.SysLoginUtil;
import net.sf.json.JSONArray;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 文件上传记录 控制器
 * @author wuluodan
 *
 */
@Controller
@RequestMapping(value="uploadFile")
public class UploadFileController extends CommonController {

	private final static Logger LOGGER = Logger.getLogger(UploadFileController.class);

	@Autowired
	private IUploadFileService uploadFileService;

	@Autowired
	private IWebSmRecService webSmRecService;

	@Autowired
	private ISvrNodeDefService svrNodeDefService;

	/**
	 * 查询
	 * @param page
	 * @param request
	 * @return QueryPage
	 */
	@ResponseBody
	@RequestMapping(value="query")
	public QueryPage<?> query(QueryPage<?> page, HttpServletRequest request) {
		super.logType = SmLog.LOGTYPE_SELECT;
		super.logContent = "[" + SysLoginUtil.getLoginUserId() + "]查询文件上传记录";
		page.setParams(getParams(request));
		QueryPage<?> result = null;
		try {
			result = uploadFileService.selectPage(page);
		} catch (Exception e) {
			LOGGER.error("查询文件上传记录信息出现异常：" + e.getMessage(), e);
			super.logResult = SmLog.RESULT_FAIL;
		}
		super.saveSmLog(super.logType, super.logContent, super.logResult);
		return result;
	}

	/**
	 * 获取参数信息
	 * @param request
	 * @return Map<String, Object>
	 */
	private Map<String, Object> getParams(HttpServletRequest request) {
		String fileName = request.getParameter("fileName");
		String userName = request.getParameter("userName");
		String auditStatus = request.getParameter("auditStatus");
		String startDate = request.getParameter("startDate");
		String endDate = request.getParameter("endDate");
		String blackUser = request.getParameter("blackUser");
		String invalidUser = request.getParameter("invalidUser");

		String fileType = request.getParameter("fileType"); 		// 文件导入标识
		String svrNode = request.getParameter("svrNode"); 			// 业务端
		String serviceCode = request.getParameter("serviceCode"); 	// 短信类型

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("fileName", fileName);
		params.put("userName", userName);
		params.put("auditStatus", auditStatus);
		params.put("startDate", startDate);
		params.put("endDate", endDate);
		params.put("blackUser", blackUser);
		params.put("invalidUser", invalidUser);

		params.put("fileType", fileType);
		params.put("svrNode", svrNode);
		params.put("serviceCode", serviceCode);
		return params;
	}

	/**
	 * 审核
	 * @param fileId 文件ID
	 * @param auditStatus 审核状态
	 * @return Message
	 */
	@ResponseBody
	@RequestMapping(value="audit")
	public Message audit(String fileId, String auditStatus) {
		try {
			UploadFile entity = uploadFileService.selectByPrimaryKey(fileId);
			entity.setAuditStatus(auditStatus);
			uploadFileService.changeAuditStatus(entity);
			return new Message(true, "审核成功！");
		} catch (Exception e) {
			LOGGER.error("审核文件上传记录信息出现异常：" + e.getMessage(), e);
			return new Message(false, "审核失败！");
		}
	}

	/**
	 * 生效/失效
	 * @param fileId 文件ID
	 * @param status 状态
	 * @return Message
	 */
	@ResponseBody
	@RequestMapping(value="changeStatus")
	public Message changeStatus(String fileIds, String status, String fileType) {
		String[] arr = fileIds.split(",");
		try {
			uploadFileService.changeStatus(arr, status, fileType);
			return new Message(true, "操作成功！");
		} catch (Exception e) {
			LOGGER.error("生效/失效文件出现异常：" + e.getMessage(), e);
			return new Message(false, "操作失败！");
		}
	}

	/**
	 * 删除
	 * @param fileId 文件ID
	 * @return Message
	 */
	@ResponseBody
	@RequestMapping(value="delete")
	public Message delete(String fileIds, String fileType) {
		super.logType = SmLog.LOGTYPE_DELETE;
		super.logContent = "[" + SysLoginUtil.getLoginUserId() + "]删除文件上传记录";
		boolean isSuccess = true;
		String msg;
		try {
			uploadFileService.deleteBatch(fileIds, fileType);
			msg = "删除成功！";
		} catch (Exception e) {
			LOGGER.error("删除文件上传记录信息出现异常：" + e.getMessage(), e);
			super.logResult = SmLog.RESULT_FAIL;
			isSuccess = false;
			msg = "删除失败！";
		}
		super.saveSmLog(super.logType, super.logContent, super.logResult);
		return new Message(isSuccess, msg);
	}

	/**
	 * 修改页面数据准备
	 * @param fileId 文件ID
	 * @return UploadWebSmDTO
	 */
	@ResponseBody
	@RequestMapping(value="toUpdate")
	public UploadWebSmDTO toUpdate(String fileId) {
		try {
			return uploadFileService.toUpdate(fileId);
		} catch (Exception e) {
			LOGGER.error("文件上传修改页面数据准备出现异常：" + e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 修改
	 * @param request
	 * @param file
	 * @param fileType
	 * @param fileId
	 * @return
	 * @throws Exception
	 */
	@ResponseBody
	@RequestMapping(value="update")
	public String update(HttpServletRequest request, @RequestParam(value="file", required=false)MultipartFile file
			, String fileType, String fileId) throws Exception {
		super.logType = SmLog.LOGTYPE_UPDATE;
		super.logContent = "[" + SysLoginUtil.getLoginUserId() + "]修改短信文件导入";
		boolean isSuccess = true;
		String msg;
		try {
			// 门户短信文件导入
			if (fileType.equals(ComConstant.SMS_PHONE)) {
				String isEdit = request.getParameter("isEdit");
				// 文件为空，只修改短信信息
				if (null == file || file.isEmpty() || (StringUtils.isNotBlank(isEdit) && isEdit.toString().equals("false"))) {
					List<WebSmRec> listWebSmRec = webSmRecService.getByFileId(fileId);
					for (WebSmRec webSmRec : listWebSmRec) {
						webSmRec.setSvrNode(request.getParameter("svrNode"));
						webSmRec.setServiceCode(request.getParameter("serviceCode"));
						webSmRec.setSendPort(request.getParameter("sendPort"));
						webSmRec.setRemark(request.getParameter("remark"));
						if (webSmRec.getSendMode().equals(WebSmRec.SEND_MODE_MASS_PHONE)) {
							webSmRec.setSmContent(request.getParameter("smContent"));
						}
					}
					webSmRecService.updateBatch(listWebSmRec);
				} else {
					Map<String, Object> map = new HashMap<String, Object>();
					if (fileType.equals(ComConstant.SMS_PHONE)) {
						map.put("smsPhone", getParamsWebSmRec(request));
					}

					if (!(StringUtils.endsWith(file.getOriginalFilename(), ".txt") || StringUtils.endsWith(file.getOriginalFilename(), ".csv")
							|| StringUtils.endsWith(file.getOriginalFilename(), ".xls")
							|| StringUtils.endsWith(file.getOriginalFilename(), ".xlsx"))) {
						return JSONArray.fromObject(new Message(false, URLEncoder.encode("文件格式不正确！", "UTF-8"))).toString();
					}

					String dirPath = ContextPropertiesUtils.getProperty("file_base_dir");
					File tmpFile = new File(dirPath);
					if (!tmpFile.exists()) tmpFile.mkdirs();

					// 检查是否有同名文件
					String fileName = file.getOriginalFilename();
					String saveFileName = fileName; // 修改上传到服务器的文件名
					int i = 1;
					while (true) {
						String tmpFilePath = dirPath + "/" + saveFileName;
						tmpFile = new File(tmpFilePath);
						if (tmpFile.exists()) {
							if (StringUtils.endsWith(saveFileName, ".txt"))
								saveFileName = fileName.substring(0, fileName.indexOf(".txt")) + "(" + i + ").txt";
							else if (StringUtils.endsWith(saveFileName, ".csv"))
								saveFileName = fileName.substring(0, fileName.indexOf(".csv")) + "(" + i + ").csv";
							else if (StringUtils.endsWith(saveFileName, ".xls"))
								saveFileName = fileName.substring(0, fileName.indexOf(".xls")) + "(" + i + ").xls";
							else if (StringUtils.endsWith(saveFileName, ".xlsx"))
								saveFileName = fileName.substring(0, fileName.indexOf(".xlsx")) + "(" + i + ").xlsx";
							i++;
						} else break;
					}

					try {
						String filePath = dirPath + "/" + saveFileName;
						file.transferTo(new File(filePath));

						// 修改文件信息
						UploadFile uploadFile = uploadFileService.getById(fileId);
						uploadFile.setFileName(fileName);
						uploadFile.setFileType(fileType);
						uploadFile.setFileFormat(fileName.substring(fileName.lastIndexOf(".") + 1));
						uploadFile.setRealFileName(filePath);

						List<List<String>> dataList = null;
						if (StringUtils.endsWith(file.getOriginalFilename(), ".txt")) {
							dataList = FileUtils.readToList(filePath, FileUtils.getFileCharset(filePath));

						} else if (StringUtils.endsWith(file.getOriginalFilename(), ".csv")) {
							dataList = CsvUtils.readToList(filePath, FileUtils.getFileCharset(filePath));

						} else if (StringUtils.endsWith(file.getOriginalFilename(), ".xls")) {
							dataList = ExcelUtils.readToStringList(filePath);

						} else if (StringUtils.endsWith(file.getOriginalFilename(), ".xlsx")) {
							dataList = ExcelUtils.readToStringList(filePath);
						}
						uploadFileService.update(uploadFile, dataList, map);
					} catch (Exception e) {
						LOGGER.error("文件上传失败", e);
						super.logResult = SmLog.RESULT_FAIL;
						isSuccess = false;
						msg = "文件上传失败！";
						super.saveSmLog(super.logType, super.logContent, super.logResult);
						return JSONArray.fromObject(new Message(isSuccess, URLEncoder.encode(msg, "UTF-8"))).toString();
					}
				}

			}
			msg = "操作成功！";
			super.saveSmLog(super.logType, super.logContent, super.logResult);
			return JSONArray.fromObject(new Message(isSuccess, URLEncoder.encode(msg, "UTF-8"))).toString();
		} catch (Exception e) {
			LOGGER.error("修改文件上传记录信息出现异常：" + e.getMessage(), e);
			super.logResult = SmLog.RESULT_FAIL;
			isSuccess = false;
			msg = "操作失败！";
			super.saveSmLog(super.logType, super.logContent, super.logResult);
			return JSONArray.fromObject(new Message(isSuccess, URLEncoder.encode(msg, "UTF-8"))).toString();
		}
	}

	/**
	 * 导出 Excel
	 * @param request
	 * @param response
	 */
	@RequestMapping(value="/out-excel", method=RequestMethod.POST)
	public void outExcel(HttpServletRequest request, HttpServletResponse response) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
		String fileName = "文件上传记录信息表";

		Map<String, Object> params = new HashMap<String, Object>();
		for (Object name : request.getParameterMap().keySet()) {
			params.put(name.toString(), request.getParameter(name.toString()));
		}

		HSSFWorkbook wb = null;
		String fileType = request.getParameter("fileType"); 		// 文件导出标识
		if (StringUtils.isNotBlank(fileType)) {
			if (fileType.equals(ComConstant.SMS_PHONE)) {
				List<UploadWebSmDTO> list = uploadFileService.getRecordWebSmRec(params);
				if (null == list || 0 == list.size()) {
					list.add(new UploadWebSmDTO());
				}
				wb = (HSSFWorkbook)CreateExcel
						.getInstance()
						.CreateNewExcelNoTemplate(fileName, list).getWorkbook();
			} else if (fileType.equals(ComConstant.ERROR_MNG)) {
				List<UploadFileDTO> list = uploadFileService.getRecord(params);
				if (null == list || 0 == list.size()) {
					list.add(new UploadFileDTO());
				}
				wb = (HSSFWorkbook)CreateExcel
						.getInstance()
						.CreateNewExcelNoTemplate(fileName, list).getWorkbook();
			}
		}

		OutputStream fOut = null;
		try {
			fileName = new String(fileName.getBytes("gbk"), "ISO8859-1");
			response.reset();
			response.setContentType("application/octet-stream; charset=utf-8");
			response.setHeader("Content-Disposition",
					"attachment;filename="+fileName+sdf.format(new Date())+".xls");
			fOut = response.getOutputStream();
			wb.write(fOut);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				fOut.flush();
				fOut.close();
			} catch (IOException e) {

			}
		}
	}

	/**
	 * 导入
	 * @param request
	 * @param file
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="upload")
	@ResponseBody
	public String upload(HttpServletRequest request, @RequestParam(value="file", required=false)MultipartFile file, String fileType)
			throws Exception {
		/*if (!(StringUtils.endsWith(file.getOriginalFilename(), ".txt") || StringUtils.endsWith(file.getOriginalFilename(), ".csv")
				|| StringUtils.endsWith(file.getOriginalFilename(), ".xls") || StringUtils.endsWith(file.getOriginalFilename(), ".xlsx"))) {
			return JSONArray.fromObject(new Message(false, URLEncoder.encode("文件格式不正确！", "UTF-8"))).toString();
		}*/

		Map<String, Object> map = new HashMap<String, Object>();
		if (fileType.equals(ComConstant.SMS_PHONE)) {
			map.put("smsPhone", getParamsWebSmRec(request));
		}

		if (!file.isEmpty()) {
			String dirPath = ContextPropertiesUtils.getProperty("file_base_dir");
			File tmpFile = new File(dirPath);
			if (!tmpFile.exists()) tmpFile.mkdirs();

			// 检查是否有同名文件
			String fileName = file.getOriginalFilename();
			String saveFileName = fileName; // 修改上传到服务器的文件名
			int i = 1;
			while (true) {
				String tmpFilePath = dirPath + "/" + saveFileName;
				tmpFile = new File(tmpFilePath);
				if (tmpFile.exists()) {
					if (StringUtils.endsWith(saveFileName, ".txt"))
						saveFileName = fileName.substring(0, fileName.indexOf(".txt")) + "(" + i + ").txt";
					else if (StringUtils.endsWith(saveFileName, ".csv"))
						saveFileName = fileName.substring(0, fileName.indexOf(".csv")) + "(" + i + ").csv";
					else if (StringUtils.endsWith(saveFileName, ".xls"))
						saveFileName = fileName.substring(0, fileName.indexOf(".xls")) + "(" + i + ").xls";
					else if (StringUtils.endsWith(saveFileName, ".xlsx"))
						saveFileName = fileName.substring(0, fileName.indexOf(".xlsx")) + "(" + i + ").xlsx";
					i++;
				} else break;
			}

			try {
				String filePath = dirPath + "/" + saveFileName;
				file.transferTo(new File(filePath));

				// 保存文件信息
				UploadFile uploadFile = new UploadFile();
				uploadFile.setFileName(fileName);
				uploadFile.setFileType(fileType);
				uploadFile.setFileFormat(fileName.substring(fileName.lastIndexOf(".") + 1));
				uploadFile.setRealFileName(filePath);

				List<List<String>> dataList = null;
				if (StringUtils.endsWith(file.getOriginalFilename(), ".txt")) {
					dataList = FileUtils.readToList(filePath, FileUtils.getFileCharset(filePath));

				} else if (StringUtils.endsWith(file.getOriginalFilename(), ".csv")) {
					dataList = CsvUtils.readToList(filePath, FileUtils.getFileCharset(filePath));

				} else if (StringUtils.endsWith(file.getOriginalFilename(), ".xls")) {
					dataList = ExcelUtils.readToStringList(filePath);

				} else if (StringUtils.endsWith(file.getOriginalFilename(), ".xlsx")) {
					dataList = ExcelUtils.readToStringList(filePath);
				}
				uploadFileService.saveUploadData(uploadFile, dataList, map);
			} catch (Exception e) {
				LOGGER.error("文件上传失败", e);
				return JSONArray.fromObject(new Message(false, URLEncoder.encode("文件上传失败！", "UTF-8"))).toString();
			}
			return JSONArray.fromObject(new Message(true, URLEncoder.encode("上传成功！", "UTF-8"))).toString();
		} else {
			return JSONArray.fromObject(new Message(false, URLEncoder.encode("文件不存在！", "UTF-8"))).toString();
		}
	}

	/**
	 * 获取上传短信文件的参数信息
	 * @param request
	 * @return Map<String, Object>
	 */
	private Map<String, Object> getParamsWebSmRec(HttpServletRequest request) {
		String sendPort = "";
		if (StringUtils.isNotBlank(request.getParameter("svrNode"))) {
			SvrNodeDef svrNodeDef = svrNodeDefService.selectByPrimaryKey(request.getParameter("svrNode"));
			sendPort = svrNodeDef.getSendPort() + request.getParameter("sendPort");
		}

		Map<String, Object> params = new HashMap<String, Object>();
		params.put("svrNode", request.getParameter("svrNode"));
		params.put("serviceCode", request.getParameter("serviceCode"));
		params.put("sendPort", sendPort);
		params.put("sendMode", request.getParameter("sendMode"));
		params.put("smContent", request.getParameter("smContent"));
		params.put("remark", request.getParameter("remark"));
		return params;
	}

	/**
	 * 提供 .txt/.csv/.xls/.xlsx 模板下载
	 * @param fileName
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value="download")
	public void download(String fileName, HttpServletRequest request, HttpServletResponse response) throws UnsupportedEncodingException {
		super.logType = SmLog.LOGTYPE_DOWNLOAD;
		super.logContent = "[" + SysLoginUtil.getLoginUserId() + "]下载文件模板";
		response.setCharacterEncoding("utf-8");
		response.setContentType("multipart/form-data");
//		response.setHeader("Content-Disposition", "attachment;fileName="
//				+new String(fileName.getBytes("gb2312"), "ISO8859-1"));
		String name = fileName;
		//可能会乱码
		if(!fileName.startsWith("号码群发")){
			name = new String(fileName.getBytes("ISO-8859-1"),"UTF-8");
		}

		String agent = request.getHeader("user-agent");
        if (agent.contains("Firefox")) {
			response.addHeader(
					"Content-Disposition",
					"attachment;filename="
							+ new String(name.getBytes("GB2312"),
							"ISO-8859-1"));
		} else {
			response.addHeader(
					"Content-Disposition",
					"attachment;filename="
							+ URLEncoder.encode(name, "UTF-8"));
		}

        OutputStream os=null;
        InputStream inputStream = null;
		try {
            String path = request.getSession().getServletContext().getRealPath("excel") + File.separator;
			inputStream = new FileInputStream(new File(path + name));

			os = response.getOutputStream();
			byte[] b = new byte[2048];
			int length;
			while ((length = inputStream.read(b)) > 0) {
				os.write(b, 0, length);
			}
		} catch (Exception e) {
			LOGGER.error("下载文件模板出现异常：" + e.getMessage(), e);
			super.logResult = SmLog.RESULT_FAIL;
		}finally {
			try {
				// 这里主要关闭。
				if (os != null) {
					os.close();
				}
				if (inputStream != null) {
					inputStream.close();
				}
			} catch (IOException e) {
					e.printStackTrace();
			}
		}
		super.saveSmLog(super.logType, super.logContent, super.logResult);
	}
}
